<template>
	<onez-view class="onez-node" :id="tmpId" :viewid="tmpId"
		:class="{ event: info_ && info_.event && !info_.is_scene, cursor: info_ && info_.event && !info_.is_scene }"
		v-if="ready" :style="{
      position: info_ && info_.position ? info_.position : position,
      left: info_ && info_.left ? info_.left + 'px' : '0',
      top: info_ && info_.top ? info_.top + 'px' : '0',
      marginLeft: -center[0] + 'px',
      marginTop: -center[1] + 'px',
      width: width ? width + 'px' : 'auto',
      height: height ? height + 'px' : 'auto',
      opacity: opacity,
      transform: 'translate3d(' + x + 'px,' + y + 'px,' + z + 'px) rotate3d(' + rX + ',' + rY + ',' + rZ + ',' + r + 'deg) scale3d(' + scaleX + ',' + scaleY + ',' + scaleZ + ')',
      transition: transition
    }" @click.native="hit">
		<onez-view class="node-bg-box" v-if="info_ && pic" :style="{
        width: width ? width + 'px' : 'auto',
        height: height ? height + 'px' : 'auto'
      }">
			<onez-view class="node-bg-border" :style="{
          transform: 'translate3d(' + posX + 'px,' + posY + 'px,0px)'
        }">
				<onez-view class="node-bg" :style="{
            width: info_.resWidth + 'px',
            height: info_.resHeight + 'px',
            backgroundImage: pic ? 'url(' + pic + ')' : 'none',
            backgroundSize: backgroundSize,
            backgroundPosition: backgroundPosition
          }"></onez-view>
			</onez-view>
		</onez-view>
		<onez-view class="node-front">
			<template v-if="children" v-for="(node, index) in children">
				<onez-node :info="node.info" :show="node.show" :resid="node.resid" :play="node.play"
					:ref="node.key"></onez-node>
			</template>
			<slot></slot>
			<onez-view viewid="node.text" v-if="info_.text" :style="info_.textStyle">{{ info_.text }}</onez-view>
		</onez-view>
	</onez-view>
</template>
<script>
	/**
	 */
	import onezView from '../onez-view/onez-view.vue'
	export default {
		name: 'onez-node',
		components: {
			onezView
		},
		props: {
			info: {
				type: Object,
				default: null
			},
			winSize: {
				type: Object,
				default: null
			},
			resid: {
				type: String,
				default: null
			},
			show: {
				type: Boolean,
				default: true
			},
			play: {
				type: Boolean,
				default: true
			},
			dir: {
				type: String,
				default: 'b'
			},
			position: {
				type: String,
				default: 'absolute'
			}
		},
		data() {
			return {
				tmpId: 'node' + (Math.random() + '').split('.')[1],
				transition: 'none',
				backgroundSize: 'auto',
				backgroundPosition: null,
				ready: false,
				pic: null,
				info_: null,
				dirs: [],
				children: [],
				num: 0,
				col: 1,
				row: 1,
				playIndex: [0, 0],
				center: [0, 0],
				width: 0,
				height: 0,
				posX: 0,
				posY: 0,
				cX: 0,
				cY: 0,
				cZ: 0,
				x: 0,
				y: 0,
				z: 0,
				rX: 0,
				rY: 0,
				rZ: 0,
				r: 0,
				opacity: 1,
				scaleX: 1,
				scaleY: 1,
				scaleZ: 1
			};
		},
		watch: {
			info(nVal, oVal) {
				this.update();
			},
			winSize(nVal, oVal) {
				this.update();
			},
			dir(nVal, oVal) {
				this.updateDir();
			}
		},
		mounted() {
			this.init();
		},
		destroyed() {
			this.$game.$off('global-update', this.onGlobalUpdate);
		},
		methods: {
			onGlobalUpdate(e) {
				if (e.detail) {
					e = e.detail;
				}
				//console.log('~~~~~~~~~~~~~~~~~~~~~~', e);
				if (e.key && e.key == this.info_.global.key) {
					let o = this.info_.global.field.split('.');
					if (o.length == 1) {
						this.info_[o[0]] = e.value;
					} else if (o.length == 2) {
						this.info_[o[0]][o[1]] = e.value;
					}
					this.update(true);
				}
			},
			updateDir() {
				if (this.dirs.length == 0) {
					return;
				}
				var index = this.dirs.indexOf(this.dir);
				if (index == -1) {
					index = 0;
				}
				this.posY = -index * this.height;
			},
			async init() {
				let info = this.info || {};
				if (this.resid) {
					let request = info.request || {};
					request.resid = this.resid;
					let r = await this.$game.hook(this, 'res', request);
					if (r) {
						info = Object.assign(r, info);
					}
				}
				if (info.global) {
					this.$game.$off('global-update', this.onGlobalUpdate);
					this.$game.$on('global-update', this.onGlobalUpdate);
				}
				this.info_ = info;
				await this.update();
				this.$emit('init', info);
				this.updateDir();
				this.ready = true;
			},
			async update(force) {
				let info = this.info_;
				if (info) {
					if (force) {
						if (this.resid) {
							let request = info.request || {};
							request.resid = this.resid;
							let r = await this.$game.hook(this, 'res', request);
							if (r) {
								info = Object.assign(info, r);
								this.info_ = info;
							}
						}
					}
					if (info.children) {
						this.children = info.children;
					}
					if (info.x) {
						this.x = info.x;
					}
					if (info.y) {
						this.y = info.y;
					}
					if (info.pic) {
						this.pic = info.pic;
						var r = await this.$game.loadRes(info.pic);
						info.resWidth = info.width || r.width;
						info.resHeight = info.height || r.height;
						this.resWidth = r.width;
						this.resHeight = r.height;
						if (info.num) {
							this.num = info.num;
						}
						if (info.width) {
							this.backgroundSize = '100% 100%';
							this.width = info.width;
							this.height = info.height;
						} else {
							if (info.col) {
								var col = info.col;
								var row = info.row || 1;
								if (info.dir) {
									this.dirs = info.dir.split(',');
									row = this.dirs.length;
								}
								this.col = col;
								this.row = row;
								this.width = this.resWidth / col;
								this.height = this.resHeight / row;
							} else {
								this.width = this.resWidth;
								this.height = this.resHeight;
							}
							if (info.speed && this.play) {
								setInterval(this.animate, info.speed);
							}
						}
						if (info.center) {
							if (info.center[0] <= 1) {
								this.cX = this.width * info.center[0];
							} else {
								this.cX = info.center[0];
							}
							if (info.center[0] <= 1) {
								this.cY = this.height * info.center[1];
							} else {
								this.cY = info.center[1];
							}
							this.center = [this.cX, this.cY];
						}
						if (info.mode) {
							if (info.mode == 'cover') {
								this.info_.resWidth = this.$game.width;
								this.info_.resHeight = this.$game.height;
								this.width = this.$game.width;
								this.height = this.$game.height;
								this.backgroundSize = 'cover';
								this.backgroundPosition = 'center';
							} else if (info.mode == 'full') {
								this.info_.resWidth = this.$game.width;
								this.info_.resHeight = this.$game.height;
								this.width = this.$game.width;
								this.height = this.$game.height;
								this.backgroundSize = '100% 100%';
								this.backgroundPosition = 'center';
							}
						}
					}
					this.updateDir();
				}
				await this.$game.wait(this);
			},
			animate() {
				if (!this.show) {
					return;
				}
				this.playIndex[0]++;
				if (this.playIndex[0] >= this.col) {
					if (this.dirs.length > 0) {
						this.playIndex[0] = 0;
					} else {
						this.playIndex[0] = 0;
						this.playIndex[1]++;
						if (this.playIndex[1] >= this.row) {
							this.playIndex = [0, 0];
						}
					}
				}
				if (this.num && this.playIndex[1] * this.row + this.playIndex[0] >= this.num) {
					this.playIndex = [0, 0];
				}
				this.posX = -this.playIndex[0] * this.width;
				if (this.dirs.length == 0) {
					this.posY = -this.playIndex[1] * this.height;
				}
				this.$forceUpdate();
			},
			async playOnce() {
				if (this.info_ && this.info_.num) {
					this.playIndex = [0, 0];
					let sec = (this.info_.speed || 60) * 0.001;
					for (var i = 0; i < this.info_.num; i++) {
						this.posX = -this.playIndex[0] * this.width;
						this.posY = -this.playIndex[1] * this.height;
						await this.$game.delay(sec);
						this.playIndex[0]++;
						if (this.playIndex[0] >= this.col) {
							this.playIndex[0] = 0;
							this.playIndex[1]++;
						}
					}
					await this.$game.delay(sec);
				}
			},
			async goTo(x, y) {
				var msec = 0;
				if (typeof x == 'object') {
					msec = x[2];
					y = x[1];
					x = x[0];
				}
				var msec = msec || 0;
				if (msec > 0) {
					this.$game.tween(this, msec * 0.001, {
						x: x,
						y: y,
						ease: 'linear.in'
					});
				} else {
					this.x = x;
					this.y = y;
				}
			},
			hit(e) {
				if (this.info_ && this.info_.event) {
					if (typeof this.info_.event == 'function') {
						this.info_.event(this);
						return;
					}
					this.$game.onEvent(this, this.info_.event);
					return;
				}
				if (e.target.id && e.target.id == this.tmpId) {
					var x = e.layerX || e.target.x;
					var y = e.layerY || e.target.y;
					this.$emit('hit', {
						x: x,
						y: y,
						event: e,
						tx: this.x,
						ty: this.y
					});
				} else if (!e.target.id) {
					var x = e.target.x;
					var y = e.target.y;
					this.$emit('hit', {
						x: x,
						y: y,
						event: e,
						tx: this.x,
						ty: this.y
					});
				}
			}
		}
	};
</script>
<style scoped>
	.onez-node {
		display: inline-block;
	}

	.node-bg-box {
		position: absolute;
		left: 0;
		top: 0;
		overflow: hidden;
		pointer-events: none;
		display: block;
	}

	.node-bg,
	.node-bg-border {
		display: block;
	}

	.node-front {
		position: relative;
		display: block;
		pointer-events: none;
	}

	.event {
		pointer-events: all !important;
	}

	.cursor {
		cursor: pointer;
	}
</style>